home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / klax.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  10KB  |  409 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/klax.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************
  8.  
  9.     Playfield encoding
  10.     ------------------
  11.         1 16-bit word is used
  12.  
  13.         Word 1:
  14.             Bits 13-15 = palette
  15.             Bits  0-12 = image number
  16.  
  17.  
  18.     Motion Object encoding
  19.     ----------------------
  20.         4 16-bit words are used
  21.  
  22.         Word 1:
  23.             Bits  0-7  = link to the next motion object
  24.  
  25.         Word 2:
  26.             Bits  0-11 = image index
  27.  
  28.         Word 3:
  29.             Bits  7-15 = horizontal position
  30.             Bits  0-3  = motion object palette
  31.  
  32.         Word 4:
  33.             Bits  7-15 = vertical position
  34.             Bits  4-6  = horizontal size of the object, in tiles
  35.             Bit   3    = horizontal flip
  36.             Bits  0-2  = vertical size of the object, in tiles
  37.  
  38. ***************************************************************************/
  39.  
  40. #include "driver.h"
  41. #include "machine/atarigen.h"
  42. #include "vidhrdw/generic.h"
  43.  
  44. #define XCHARS 42
  45. #define YCHARS 30
  46.  
  47. #define XDIM (XCHARS*8)
  48. #define YDIM (YCHARS*8)
  49.  
  50.  
  51.  
  52. /*************************************
  53.  *
  54.  *    Prototypes
  55.  *
  56.  *************************************/
  57.  
  58. static const UINT8 *update_palette(void);
  59.  
  60. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  61. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  62. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  63.  
  64. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  65. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  66.  
  67.  
  68.  
  69. /*************************************
  70.  *
  71.  *    Video system start
  72.  *
  73.  *************************************/
  74.  
  75. int klax_vh_start(void)
  76. {
  77.     static struct atarigen_mo_desc mo_desc =
  78.     {
  79.         256,                 /* maximum number of MO's */
  80.         8,                   /* number of bytes per MO entry */
  81.         2,                   /* number of bytes between MO words */
  82.         0,                   /* ignore an entry if this word == 0xffff */
  83.         0, 0, 0xff,          /* link = (data[linkword] >> linkshift) & linkmask */
  84.         0                    /* render in reverse link order */
  85.     };
  86.  
  87.     static struct atarigen_pf_desc pf_desc =
  88.     {
  89.         8, 8,                /* width/height of each tile */
  90.         64, 32,                /* number of tiles in each direction */
  91.         1                    /* non-scrolling */
  92.     };
  93.  
  94.     /* initialize the playfield */
  95.     if (atarigen_pf_init(&pf_desc))
  96.         return 1;
  97.  
  98.     /* initialize the motion objects */
  99.     if (atarigen_mo_init(&mo_desc))
  100.     {
  101.         atarigen_pf_free();
  102.         return 1;
  103.     }
  104.  
  105.     return 0;
  106. }
  107.  
  108.  
  109.  
  110. /*************************************
  111.  *
  112.  *    Video system shutdown
  113.  *
  114.  *************************************/
  115.  
  116. void klax_vh_stop(void)
  117. {
  118.     atarigen_pf_free();
  119.     atarigen_mo_free();
  120. }
  121.  
  122.  
  123.  
  124. /*************************************
  125.  *
  126.  *    Playfield RAM write handler
  127.  *
  128.  *************************************/
  129.  
  130. WRITE_HANDLER( klax_playfieldram_w )
  131. {
  132.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  133.     int newword = COMBINE_WORD(oldword, data);
  134.  
  135.     if (oldword != newword)
  136.     {
  137.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  138.         atarigen_pf_dirty[(offset & 0xfff) / 2] = 1;
  139.     }
  140. }
  141.  
  142.  
  143.  
  144. /*************************************
  145.  *
  146.  *    Latch write handler
  147.  *
  148.  *************************************/
  149.  
  150. WRITE_HANDLER( klax_latch_w )
  151. {
  152. }
  153.  
  154.  
  155.  
  156. /*************************************
  157.  *
  158.  *    Periodic scanline updater
  159.  *
  160.  *************************************/
  161.  
  162. void klax_scanline_update(int scanline)
  163. {
  164.     /* update the MOs from the SLIP table */
  165.     atarigen_mo_update_slip_512(atarigen_spriteram, 0, scanline, &atarigen_playfieldram[0xf80]);
  166. }
  167.  
  168.  
  169.  
  170. /*************************************
  171.  *
  172.  *    Main refresh
  173.  *
  174.  *************************************/
  175.  
  176. void klax_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  177. {
  178.     /* remap if necessary */
  179.     if (update_palette())
  180.         memset(atarigen_pf_dirty, 1, atarigen_playfieldram_size / 4);
  181.  
  182.     /* update playfield */
  183.     atarigen_pf_process(pf_render_callback, bitmap, &Machine->drv->visible_area);
  184.  
  185.     /* render the motion objects */
  186.     atarigen_mo_process(mo_render_callback, bitmap);
  187.  
  188.     /* update onscreen messages */
  189.     atarigen_update_messages();
  190. }
  191.  
  192.  
  193.  
  194. /*************************************
  195.  *
  196.  *    Palette management
  197.  *
  198.  *************************************/
  199.  
  200. static const UINT8 *update_palette(void)
  201. {
  202.     UINT16 mo_map[16], pf_map[16];
  203.     int i, j;
  204.  
  205.     /* reset color tracking */
  206.     memset(mo_map, 0, sizeof(mo_map));
  207.     memset(pf_map, 0, sizeof(pf_map));
  208.     palette_init_used_colors();
  209.  
  210.     /* update color usage for the playfield */
  211.     atarigen_pf_process(pf_color_callback, pf_map, &Machine->drv->visible_area);
  212.  
  213.     /* update color usage for the mo's */
  214.     atarigen_mo_process(mo_color_callback, mo_map);
  215.  
  216.     /* rebuild the playfield palette */
  217.     for (i = 0; i < 16; i++)
  218.     {
  219.         UINT16 used = pf_map[i];
  220.         if (used)
  221.             for (j = 0; j < 16; j++)
  222.                 if (used & (1 << j))
  223.                     palette_used_colors[0x100 + i * 16 + j] = PALETTE_COLOR_USED;
  224.     }
  225.  
  226.     /* rebuild the motion object palette */
  227.     for (i = 0; i < 16; i++)
  228.     {
  229.         UINT16 used = mo_map[i];
  230.         if (used)
  231.         {
  232.             palette_used_colors[0x000 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  233.             for (j = 1; j < 16; j++)
  234.                 if (used & (1 << j))
  235.                     palette_used_colors[0x000 + i * 16 + j] = PALETTE_COLOR_USED;
  236.         }
  237.     }
  238.  
  239.     return palette_recalc();
  240. }
  241.  
  242.  
  243.  
  244. /*************************************
  245.  *
  246.  *    Playfield palette
  247.  *
  248.  *************************************/
  249.  
  250. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  251. {
  252.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  253.     UINT16 *colormap = param;
  254.     int x, y;
  255.  
  256.     /* standard loop over tiles */
  257.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  258.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 31)
  259.         {
  260.             int offs = x * 32 + y;
  261.             int data1 = READ_WORD(&atarigen_playfieldram[offs * 2]);
  262.             int data2 = READ_WORD(&atarigen_playfieldram[offs * 2 + 0x1000]);
  263.             int code = data1 & 0x1fff;
  264.             int color = (data2 >> 8) & 15;
  265.  
  266.             /* mark the colors used by this tile */
  267.             colormap[color] |= usage[code];
  268.         }
  269. }
  270.  
  271.  
  272.  
  273. /*************************************
  274.  *
  275.  *    Playfield rendering
  276.  *
  277.  *************************************/
  278.  
  279. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  280. {
  281.     const struct GfxElement *gfx = Machine->gfx[0];
  282.     struct osd_bitmap *bitmap = param;
  283.     int x, y;
  284.  
  285.     /* standard loop over tiles */
  286.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  287.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 31)
  288.         {
  289.             int offs = x * 32 + y;
  290.  
  291.             /* update only if dirty */
  292.             if (atarigen_pf_dirty[offs])
  293.             {
  294.                 int data1 = READ_WORD(&atarigen_playfieldram[offs * 2]);
  295.                 int data2 = READ_WORD(&atarigen_playfieldram[offs * 2 + 0x1000]);
  296.                 int color = (data2 >> 8) & 15;
  297.                 int hflip = data1 & 0x8000;
  298.                 int code = data1 & 0x1fff;
  299.  
  300.                 drawgfx(atarigen_pf_bitmap, gfx, code, color, hflip, 0, 8 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  301.                 atarigen_pf_dirty[offs] = 0;
  302.             }
  303.         }
  304.  
  305.     /* then blast the result */
  306.     copybitmap(bitmap, atarigen_pf_bitmap, 0, 0, 0, 0, clip, TRANSPARENCY_NONE, 0);
  307. }
  308.  
  309.  
  310.  
  311. /*************************************
  312.  *
  313.  *    Playfield overrendering
  314.  *
  315.  *************************************/
  316.  
  317. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  318. {
  319.     const struct GfxElement *gfx = Machine->gfx[0];
  320.     struct osd_bitmap *bitmap = param;
  321.     int x, y;
  322.  
  323.     /* standard loop over tiles */
  324.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  325.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 31)
  326.         {
  327.             int offs = x * 32 + y;
  328.             int data2 = READ_WORD(&atarigen_playfieldram[offs * 2 + 0x1000]);
  329.             int color = (data2 >> 8) & 15;
  330.  
  331.             /* overdraw if the color is 15 */
  332.             if (color == 15)
  333.             {
  334.                 int data1 = READ_WORD(&atarigen_playfieldram[offs * 2]);
  335.                 int hflip = data1 & 0x8000;
  336.                 int code = data1 & 0x1fff;
  337.  
  338.                 drawgfx(bitmap, gfx, code, color, hflip, 0, 8 * x, 8 * y, clip, TRANSPARENCY_NONE, 0);
  339.             }
  340.         }
  341. }
  342.  
  343.  
  344.  
  345. /*************************************
  346.  *
  347.  *    Motion object palette
  348.  *
  349.  *************************************/
  350.  
  351. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  352. {
  353.     const unsigned int *usage = Machine->gfx[1]->pen_usage;
  354.     UINT16 *colormap = param;
  355.     int code = data[1] & 0x0fff;
  356.     int color = data[2] & 0x000f;
  357.     int hsize = ((data[3] >> 4) & 7) + 1;
  358.     int vsize = (data[3] & 7) + 1;
  359.     int tiles = hsize * vsize;
  360.     UINT16 temp = 0;
  361.     int i;
  362.  
  363.     for (i = 0; i < tiles; i++)
  364.         temp |= usage[code++];
  365.     colormap[color] |= temp;
  366. }
  367.  
  368.  
  369.  
  370. /*************************************
  371.  *
  372.  *    Motion object rendering
  373.  *
  374.  *************************************/
  375.  
  376. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  377. {
  378.     const struct GfxElement *gfx = Machine->gfx[1];
  379.     struct osd_bitmap *bitmap = param;
  380.     struct rectangle pf_clip;
  381.  
  382.     /* extract data from the various words */
  383.     int code = data[1] & 0x0fff;
  384.     int xpos = data[2] >> 7;
  385.     int ypos = 512 - (data[3] >> 7);
  386.     int color = data[2] & 0x000f;
  387.     int hsize = ((data[3] >> 4) & 7) + 1;
  388.     int hflip = data[3] & 0x0008;
  389.     int vsize = (data[3] & 7) + 1;
  390.  
  391.     /* adjust for height */
  392.     ypos -= vsize * 8;
  393.  
  394.     /* adjust the final coordinates */
  395.     xpos &= 0x1ff;
  396.     ypos &= 0x1ff;
  397.     if (xpos >= XDIM) xpos -= 0x200;
  398.     if (ypos >= YDIM) ypos -= 0x200;
  399.  
  400.     /* determine the bounding box */
  401.     atarigen_mo_compute_clip_8x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  402.  
  403.     /* draw the motion object */
  404.     atarigen_mo_draw_8x8(bitmap, gfx, code, color, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_PEN, 0);
  405.  
  406.     /* overrender the playfield */
  407.     atarigen_pf_process(pf_overrender_callback, bitmap, &pf_clip);
  408. }
  409.